package com.cn.por.util.freemarker;

import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.cn.por.auto.dto.FunctionGena;
import org.apache.ibatis.type.JdbcType;

import com.cn.por.auto.dto.DataModel;
import com.cn.por.auto.dto.ModelParam;
import com.cn.por.auto.entity.TableDetiles;
import com.cn.por.auto.factory.ControllerDataModelFactory;
import com.cn.por.auto.factory.DataModelFactory;
import com.cn.por.auto.factory.EntityDataModelFactory;
import com.cn.por.auto.factory.InterfaceDataModelFactory;
import com.cn.por.auto.factory.MapperDataModelFactory;
import com.cn.por.auto.factory.ServiceDataModelFactory;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateNotFoundException;


public class FreeMarkerUtil {
	
	private static Configuration cfg = null;
	static {
		cfg = new Configuration(Configuration.VERSION_2_3_31);
		try {
			ClassLoader classLoader = FreeMarkerUtil.class.getClassLoader();
			URL resource = classLoader.getResource("generator");
			if(null!=resource){
				cfg.setDirectoryForTemplateLoading(new File(resource.toURI()));
			}
		} catch (IOException | URISyntaxException e) {
			e.printStackTrace();
		}
		cfg.setDefaultEncoding("utf-8");
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
	}
	
	public static void dataTransformer(DataModel dataModel) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		Template temp = cfg.getTemplate(dataModel.getFtlName());
		/**
		 * 创建未存在的目录
		 */
		String dirString = dataModel.getFilePath();
		File dir = new File(dirString);
		if(!dir.exists()) {
			if(!dirString.endsWith(File.separator)) {
				dirString+=File.separator;
			}
			dir.mkdirs();
		}
		File f = new File(dirString+dataModel.getFileName());
		FileOutputStream fos = new FileOutputStream(f);
		Writer w = new OutputStreamWriter(fos);
		// Writer out = new OutputStreamWriter(System.out);
		temp.process(dataModel, w);
	}

	/**
	 * 根据模板生成代码块
	 * @return
	 */
	public static  String dataFormateStr (FunctionGena functionGena,String ftlName){
		String result ="";
		try {
			Template template = cfg.getTemplate(ftlName);
			StringWriter sw =new StringWriter();
			template.process(functionGena,sw);
			result = sw.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (TemplateException e) {
			throw new RuntimeException(e);
		}
		return result;
	}
	
	/**
	 * 根据传入的数据模型，结合对应的模板，生成对应的字节流
	 * @param dataModel
	 * @throws IOException 
	 * @throws ParseException 
	 * @throws MalformedTemplateNameException 
	 * @throws TemplateNotFoundException 
	 * @throws TemplateException 
	 */
	public static byte[] dataFormateByte(DataModel dataModel) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
		ByteArrayMsg bam = new ByteArrayMsg();
		byte[] result = null;
		Template temp = cfg.getTemplate(dataModel.getFtlName());
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		OutputStreamWriter out = new OutputStreamWriter(baos);
		temp.process(dataModel, out);
		result = baos.toByteArray();
		baos.close();
		out.close();
		bam.setFileName(dataModel.getFileName());
		bam.setByteArray(result);
		return result;
	}
	
	public static void main(String[] args) throws IOException, TemplateException {
		
		ModelParam modelParam = new ModelParam();
		modelParam.setBasePackage("com.cn.por.biz.personTask");
		modelParam.setPrimaryKey("id");
		modelParam.setTableName("person_task");
		
	    List<TableDetiles> tableColumn = new ArrayList<TableDetiles>();
	    TableDetiles c1 = new TableDetiles();
	    c1.setColumnName("id");
	    c1.setColumnType("VARCHAR");
	    TableDetiles c2 = new TableDetiles();
	    c2.setColumnName("name");
	    tableColumn.add(c2);
	    c2.setColumnType("VARCHAR");
	    tableColumn.add(c1);
		modelParam.setTableColumn(tableColumn);
		modelParam.setSuffixName("Mapper");
		modelParam.setFtlName("mapper.ftl");
		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") + modelParam.getSuffixName()+".xml");
		List<TableDetiles> conditionColumn = new ArrayList<TableDetiles>();
		conditionColumn.add(c2);
		conditionColumn.add(c1);
		modelParam.setConditionColumn(conditionColumn);
		
		DataModelFactory dataModelFactory = new MapperDataModelFactory();
		dataModelFactory.setProperties(modelParam);
		dataFormateByte(dataModelFactory.getDataModel());
//		
//		DataModelFactory in = new InterfaceDataModelFactory();
//		modelParam.setFtlName("interfaceDesc.ftl");
//		modelParam.setSuffixName("Dao");
//		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") + modelParam.getSuffixName()+".java");
//		modelParam.setFilePath("src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/dao/");
//		in.setProperties(modelParam);
//		dataTransformer(in.getDataModel());
//		
//		DataModelFactory entity = new EntityDataModelFactory();
//		modelParam.setFtlName("entity.ftl");
//		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") +".java");
//		modelParam.setFilePath("src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/entity/");
//		entity.setProperties(modelParam);
//		dataTransformer(entity.getDataModel());
//		
//		DataModelFactory service = new InterfaceDataModelFactory();
//		modelParam.setFtlName("interfaceDesc.ftl");
//		modelParam.setSuffixName("Service");
//		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") + modelParam.getSuffixName()+".java");
//		modelParam.setFilePath("src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/service/");
//		service.setProperties(modelParam);
//		dataTransformer(service.getDataModel());
//		
//		DataModelFactory serviceImpl = new ServiceDataModelFactory();
//		modelParam.setFtlName("classDesc.ftl");
//		modelParam.setSuffixName("Service.Impl");
//		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") + modelParam.getSuffixName().replace(".", "")+".java");
//		modelParam.setFilePath("src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/service/impl/");
//		serviceImpl.setProperties(modelParam);
//		dataTransformer(serviceImpl.getDataModel());
//		
//		
//		DataModelFactory controller = new ControllerDataModelFactory();
//		modelParam.setFtlName("classDesc.ftl");
//		modelParam.setSuffixName("Controller");
//		modelParam.setFileName(StringFormaterUtil.columnToProperty("person_task") + modelParam.getSuffixName().replace(".", "")+".java");
//		modelParam.setFilePath("src/main/java/"+ modelParam.getBasePackage().replace(".", "/")+"/controller/");
//		controller.setProperties(modelParam);
//		dataTransformer(controller.getDataModel());
	}

}
